#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
@desc: .

@Project：kuberCloudTest 
@File：l2network.py
@Author：admin
@Date：2024/4/9 15:50 
"""
from kuberCloudTest.common.basic import basicUtils
from kuberCloudTest.common.constant import OFFSET, LIMIT, AsyncType
from kuberCloudTest.common.utils import _getDetail, _getOperationType
from kuberCloudTest.exception import KuberCloudException
from kuberCloudTest.networks.urls import networkUrls


class l2networkUtils(basicUtils):

    def __init__(self, accessToken):
        super().__init__(accessToken)


def get_utils(accessToken):
    return l2networkUtils(accessToken=accessToken)


def getL2network(accessToken, l2NetworkId=None, **kwargs):
    """
    获取二层网络
    :param accessToken:
    :param l2NetworkId: 二层网络UUID
    :param kwargs: offset:
                   limit:
                   keyword: xxx
                   searchItem: 搜索项：0: 名称; 1: UUID
                   projectName: 归属项目名称
    :return:
    """
    content = get_utils(accessToken=accessToken).cloud_http_request.get(networkUrls.getL2Network.value,
                                                                        {
                                                                            'offset': kwargs.get('offset', OFFSET),
                                                                            'limit': kwargs.get('limit', LIMIT),
                                                                            'keyword': kwargs.get('keyword', ''),
                                                                            'searchItem': kwargs.get('searchItem', 0),
                                                                            'projectName': kwargs.get('searchItem', ''),
                                                                        })
    if l2NetworkId:
        total = content.get('total', 0)
        content = get_utils(accessToken=accessToken).cloud_http_request.get(
            networkUrls.getL2Network.value, {'limit': total, 'offset': OFFSET})
        content = _getDetail(content, l2NetworkId, 'ltnid')
    return content


def getL2networkById(accessToken, l2NetworkId):
    """
    获取二层网络详情
    :param accessToken:
    :param l2NetworkId:
    :return:
    """
    content = get_utils(accessToken=accessToken).cloud_http_request.get(networkUrls.getL2Network.value)
    total = content.get('total', 0)
    content = get_utils(accessToken=accessToken).cloud_http_request.get(
        networkUrls.getL2Network.value, {'limit': total, 'offset': OFFSET})
    content = _getDetail(content, l2NetworkId, 'ltnid')
    return content


def removeL2network(accessToken, l2NetworkId):
    """
    删除二层网络
    :param accessToken:
    :param l2NetworkId: 二层网络UUID
    :return:
    """
    operationType = 5103
    data = _getOperationType(operationType, AsyncType.ASYNC.value)

    data['id'] = l2NetworkId
    return get_utils(accessToken=accessToken).cloud_http_request.post(networkUrls.removeL2Network.value, data=data)


def createL2network(accessToken, name, l2Type: int, **kwargs):
    """
    创建二层网络
    :param accessToken:
    :param name: 二层网络名称
    :param l2Type: 二层网络类型
                    1: L2NoVlanNetwork
                    2: L2VlanNetwork
                    3: VxlanNetwork
    :param kwargs: clusterId: 集群UUID，当二层网络类型为 L2NoVlanNetwork 或 L2VlanNetwork 时该项为必填
                   networkCard: 网卡，当二层网络类型为 L2NoVlanNetwork 或 L2VlanNetwork 时该项为必填
                   vlanId: VlanID，类型为L2NoVlanNetwork值为 0，类型为 L2VlanNetwork 值由用户输入
                   vxlanPoolId: vxlanPoolId, 当类型为VxlanNetwork该项为必填
                   vni: vxlanvni, 当类型为VxlanNetwork该项为必填
                   projectId: 归属项目UUID
                   remark: 描述
    :return:
    """

    operationType = 5101
    data = _getOperationType(operationType, AsyncType.ASYNC.value)

    data['type'] = l2Type
    data['name'] = name
    data['projectId'] = kwargs.get('projectId', '')
    data['remark'] = kwargs.get('remark', '')

    # L2NoVlanNetwork
    if l2Type == 1:
        clusterId = kwargs.get('clusterId')
        networkCard = kwargs.get('networkCard')
        if not clusterId or not networkCard:
            raise KuberCloudException('params error', 'clusterId or networkCard is none')
        data['clusterId'] = clusterId
        data['networkCard'] = networkCard
    # L2VlanNetwork
    elif l2Type == 2:
        clusterId = kwargs.get('clusterId')
        networkCard = kwargs.get('networkCard')
        vlanId = kwargs.get('vlanId')
        if not clusterId or not networkCard or not vlanId:
            raise KuberCloudException('params error', 'clusterId or networkCard or vlanId is none')
        data['clusterId'] = clusterId
        data['networkCard'] = networkCard
        data['vlanId'] = vlanId
    # VxlanNetwork
    elif l2Type == 3:
        vxlanPoolId = kwargs.get('vxlanPoolId')
        vni = kwargs.get('vni')
        if not vxlanPoolId or not vni:
            raise KuberCloudException('params error', 'vxlanPoolId or vni is none')
        data['vxlanPoolId'] = vxlanPoolId
        data['vni'] = vni
    else:
        raise KuberCloudException('params error', 'L2network type must in (1, 2, 3)')

    return get_utils(accessToken=accessToken).cloud_http_request.post(networkUrls.createL2Network.value, data=data)


def updateL2Network(accessToken, l2NetworkId, **kwargs):
    """
    更新二层网络
    :param accessToken:
    :param l2NetworkId: 二层网络UUID
    :param kwargs: name: 二层网络名称
                   remark: 描述
    :return:
    """
    l2Network = getL2network(accessToken=accessToken, l2NetworkId=l2NetworkId).get('obj', None)
    if not l2Network:
        raise KuberCloudException('params error', 'l2Network [{}] not exist'.format(l2NetworkId))
    operationType = 5102
    data = _getOperationType(operationType, AsyncType.SYNC.value)
    data['id'] = l2NetworkId
    data['name'] = kwargs.get('name', l2Network['ltnname'])
    data['remark'] = kwargs.get('remark', l2Network['remark'])
    return get_utils(accessToken=accessToken).cloud_http_request.post(networkUrls.updateL2Network.value, data=data)


def getL2networkCluster(accessToken, l2NetworkId, loaded: bool = False, noCluster: bool = False, **kwargs):
    """
    获取二层网络关联集群信息
    :param accessToken:
    :param l2NetworkId: 二层网络UUID
    :param loaded: True时表示查询已加载到二层网络，False表示查询未加载到二层网络
    :param noCluster: True时表示是裸金属集群，False表示不是裸金属集群
    :param kwargs: offset:
                   limit:
                   keyword: xxx
    :return:
    """
    params = {
        'l2NetworkId': l2NetworkId,
        'offset': kwargs.get('offset', OFFSET),
        'limit': kwargs.get('limit', LIMIT),
        'keyword': kwargs.get('keyword', ''),
        'loaded': 1 if loaded else 0,
        'nocluster': 1 if noCluster else 0}
    return get_utils(accessToken=accessToken).cloud_http_request.get(networkUrls.getL2NetworkCluster.value, params)


def loadClusterByL2Network(accessToken, l2NetworkId, clusterId):
    """
    二层网络挂载集群
    :param accessToken:
    :param l2NetworkId: 二层网络UUID
    :param clusterId: 集群UUID
    :return:
    """
    operationType = 5104
    data = _getOperationType(operationType, AsyncType.ASYNC.value)

    data['id'] = l2NetworkId
    data['clusterId'] = clusterId

    return get_utils(accessToken=accessToken).cloud_http_request.post(
        networkUrls.loadClusterByL2Network.value, data=data)


def unloadClusterByL2Network(accessToken, l2NetworkId, clusterId):
    """
    二层网络卸载集群
    :param accessToken:
    :param l2NetworkId: 二层网络UUID
    :param clusterId: 集群UUID
    :return:
    """
    operationType = 5105
    data = _getOperationType(operationType, AsyncType.ASYNC.value)

    data['id'] = l2NetworkId
    data['clusterId'] = clusterId

    return get_utils(accessToken=accessToken).cloud_http_request.post(
        networkUrls.unloadClusterByL2Network.value, data=data)


def globalShareL2Network(accessToken, l2NetworkIds):
    """
    全局共享二层网络
    :param accessToken:
    :param l2NetworkIds: 二层网络UUID
    :return:
    """
    operationType = 5111
    data = _getOperationType(operationType, AsyncType.SYNC.value)

    data['ids'] = l2NetworkIds

    return get_utils(accessToken=accessToken).cloud_http_request.post(networkUrls.globalShareL2Network.value, data=data)


def globalRecallL2Network(accessToken, l2NetworkIds):
    """
    全局召回二层网络
    :param accessToken:
    :param l2NetworkIds: 二层网络UUID
    :return:
    """
    operationType = 5112
    data = _getOperationType(operationType, AsyncType.SYNC.value)

    data['ids'] = l2NetworkIds

    return get_utils(accessToken=accessToken).cloud_http_request.post(
        networkUrls.globalRecallL2Network.value, data=data)
